import re
from datetime import datetime

import pdfplumber


def extract_traip_info(pdf_path):
    with pdfplumber.open(pdf_path) as pdf:
        page = pdf.pages[0]
        text_lines = page.extract_text().split("\n")
        table_date =  []
        table_date.append(read_traip(text_lines))
        result = {
            "基本信息": {"类别": "火车票", "申请日期": "", "行程日期": ""},
            "表格内容": table_date,
        }
        return result
    
# def read_traip(text_lines : str):
    # # 初始化结果字典
    # result = {
    #     "发票信息": {},
    #     "行程单信息": {}
    # }

    # # 1. 遍历列表提取信息
    # for item in text_lines:
    #     item = item.strip()  # 去除首尾空格，避免干扰
    #     if not item:
    #         continue

    #     # -------------------------- 提取发票信息 --------------------------
    #     # 提取发票号码、开票日期（含关键词“发票号码”“开票日期”）
    #     if "发票号码" in item and "开票日期" in item:
    #         # 提取发票号码（“发票号码:”后到空格前的内容）
    #         invoice_num = re.search(r'发票号码:(\d+)', item).group(1)
    #         result["发票信息"]["发票号码"] = invoice_num
    #         # 提取开票日期（“开票日期:”后到末尾的内容，再转为标准格式）
    #         invoice_date_raw = re.search(r'开票日期:(\d{4}年\d{2}月\d{2}日)', item).group(1)
    #         # 转为 yyyy-MM-dd 格式
    #         invoice_date = re.sub(r'(\d{4})年(\d{2})月(\d{2})日', r'\1-\2-\3', invoice_date_raw)
    #         result["发票信息"]["开票日期"] = invoice_date

    #     # 提取购买方名称、统一社会信用代码（含关键词“购买方名称”“统一社会信用代码”）
    #     if "购买方名称" in item and "统一社会信用代码" in item:
    #         buyer_name = re.search(r'购买方名称:(.*?) 统一社会信用代码:', item).group(1)
    #         credit_code = re.search(r'统一社会信用代码:(\w+)', item).group(1)
    #         result["发票信息"]["购买方名称"] = buyer_name
    #         result["发票信息"]["购买方统一社会信用代码"] = credit_code

    #     # 提取开票金额（行程单金额即发票金额，含“￥”）
    #     if "￥" in item and "票价" not in item:  # 排除“票价:”干扰，取纯金额项
    #         result["发票信息"]["开票金额"] = item
    #         result["行程单信息"]["金额"] = item  # 行程单金额与发票金额一致

    #     # -------------------------- 提取行程单信息 --------------------------
    #     # 提取起点、终点（含车站名称，如“北京南”“武进”，且无特殊关键词）
    #     if ("北京南" in item or "武进" in item) and "站" not in item and "Beijing" not in item:
    #         # 分割“起点 车次 终点”（如“北京南 G141 武进”）
    #         parts = item.split()
    #         if len(parts) >= 3:
    #             result["行程单信息"]["起点"] = parts[0]
    #             result["行程单信息"]["终点"] = parts[2]

    #     # 补充终点（处理拆分的“站 站”，结合前一个车站信息）
    #     if item == "站 站" and result["行程单信息"].get("终点"):
    #         result["行程单信息"]["起点"] += "站"
    #         result["行程单信息"]["终点"] += "站"

    #     # 提取开始时间（含“开”字，如“2025年09月30日 13:34开”）
    #     if "开" in item and "年" in item and "月" in item:
    #         start_time_raw = re.search(r'(\d{4}年\d{2}月\d{2}日 \d{2}:\d{2})开', item).group(1)
    #         # 转为 yyyy-MM-dd HH:mm 标准格式
    #         start_time = re.sub(r'(\d{4})年(\d{2})月(\d{2})日', r'\1-\2-\3', start_time_raw)
    #         result["行程单信息"]["开始时间"] = start_time
    #     return result
def read_traip(text_lines: list) -> dict:
    """
    读取行程单文本列表，提取发票信息和行程单信息（适配所有车站）
    :param text_lines: 行程单文本行列表（如 ['北京南 G141 武进', '2025年09月30日 13:34开', ...]）
    :return: 包含发票信息和行程单信息的字典
    """
    # 初始化结果字典
    result = {
        "type": "火车票",
        "发票信息": {},
        "行程单信息": {}
    }

    # 1. 遍历所有文本行，完整提取信息（return 移到循环外，确保遍历全部行）
    for item in text_lines:
        item = item.strip()  # 去除首尾空格，避免空白字符干扰
        if not item:
            continue  # 跳过空行

        # -------------------------- 提取发票信息（逻辑不变，确保稳定） --------------------------
        # 提取发票号码 + 开票日期（含两个关键词的行）
        if "发票号码" in item and "开票日期" in item:
            # 发票号码：匹配“发票号码:”后的数字
            invoice_num_match = re.search(r'发票号码:(\d+)', item)
            if invoice_num_match:
                result["发票信息"]["发票号码"] = invoice_num_match.group(1)
            # 开票日期：匹配“开票日期:”后的日期，转为 yyyy-MM-dd
            invoice_date_match = re.search(r'开票日期:(\d{4}年\d{1,2}月\d{1,2}日)', item)
            if invoice_date_match:
                invoice_date_raw = invoice_date_match.group(1)
                # invoice_date_std = re.sub(r'(\d{4})年(\d{1,2})月(\d{1,2}日)', r'\1-\2-\3', invoice_date_raw)
                result["发票信息"]["开票日期"] = get_date(invoice_date_raw)

        # 提取购买方名称 + 统一社会信用代码
        if "购买方名称" in item and "统一社会信用代码" in item:
            buyer_name_match = re.search(r'购买方名称:(.*?) 统一社会信用代码:', item)
            if buyer_name_match:
                result["发票信息"]["购买方名称"] = buyer_name_match.group(1)
            credit_code_match = re.search(r'统一社会信用代码:(\w+)', item)
            if credit_code_match:
                result["发票信息"]["购买方纳税人编号"] = credit_code_match.group(1)

        # 提取开票金额（含￥且不含“票价”，避免与行程单票价标签冲突）
        if "￥" in item and "票价" not in item:
            result["发票信息"]["价税合计"] = item
            result["行程单信息"]["金额"] = item 

        # -------------------------- 提取行程单信息（核心优化：适配所有车站） --------------------------
        # 关键逻辑：通过“车次特征”识别车站行（而非固定车站名）
        # 匹配常见车次格式：G(高铁)/D(动车)/C(城际)/Z(直达)/T(特快)/K(快速) + 数字（如 G141、D2345）
        train_pattern = r'[GCDZTK]\d+'
        train_match = re.search(train_pattern, item)
        
        # 车站行特征：含车次 + 不含干扰词（排除“站”“英文”“日期”“票价”等）
        if train_match and not any(keyword in item for keyword in [
            "站", "Beijing", "Shanghai", "Guangzhou",  # 排除英文车站名、“站”字行
            "年", "月", "日", "开", "票价", "￥"        # 排除日期、时间、金额行
        ]):
            # 分割行：按空格拆分为 [起点, 车次, 终点] 或 [起点, 车次, 终点, 其他信息]
            parts = item.split()
            # 确保至少有“起点、车次、终点”3部分（容错：避免异常格式导致索引错误）
            if len(parts) >= 3:
                # 起点：取分割后的第一部分（如“上海虹桥 D234 杭州东”→ 上海虹桥）
                result["行程单信息"]["起点"] = parts[0]
                # 终点：取分割后的最后一部分（适配车次后带额外信息的情况，如“深圳北 G82 长沙南 08:00”→ 长沙南）
                result["行程单信息"]["终点"] = parts[-1]

        # 补全“站”字：遇到“站 站”行，给已提取的起点/终点加“站”（通用适配）
        if item == "站 站":
            if result["行程单信息"].get("起点"):
                result["行程单信息"]["起点"] += "站"
            if result["行程单信息"].get("终点"):
                result["行程单信息"]["终点"] += "站"

        # 提取开始时间（适配单/双位数日期/时间，如“2025年9月3日 8:30开”）
        if "开" in item and "年" in item:
            start_time_match = re.search(r'(\d{4}年\d{1,2}月\d{1,2}日 \d{1,2}:\d{2})开', item)
            if start_time_match:
                start_time_raw = start_time_match.group(1)
                start_time_std= get_date_time_info(start_time_raw)
                result["行程单信息"]["用车时间"] = start_time_std

    # 2. 遍历完成后，返回完整结果（原return在循环内，此处修正）
    return result

def clear_n(headers):
    for header in headers:
        header=header.replace("\n","")
    
def multiple_lines(row,headers):
    index = 0
    for header in headers:
        if header == "终点" or header == "起点":
            if ' ' in row[index] and is_amount_with_unit(row[index + 1]):
                element = row[index]
                elements = row[index].split(" ")
                row[index] = elements[0]
                money = row[index + 1]
                row[index + 1] = elements[1]
                row.append(money)
                # row.indert(index + 2,money)
            break
        index += 1 
  
    print(len(row))
    print(row)
    print(headers)
    return row

def is_amount_with_unit(element):
    """判断字符串是否为“金额+单位”格式"""
    # 正则规则：数字（可含小数点，最多两位小数）+“元”结尾
    pattern = r'^\d+\.\d{2}元$'
    pattern2=r'^\d+\.\d{2}$'
    return bool(re.match(pattern, element)) or bool(re.match(pattern2,element))

def split_with_datetime(s):
    datetimes = get_date_time_info(s[0])
    placeholder = "||DATETIME||"
    start = ""
    # 替换日期时间为占位符
    s_replaced = s[0]
    # for dt in datetimes:

    s_replaced = s_replaced.replace(datetimes, placeholder, 1)

    if "\n" in s_replaced:
        ss = s_replaced.split("\n")
        for s2 in ss:
            if placeholder in s2:
                s_replaced = s2
            else:
                start += s2
        print(start)

    # 分割字符串
    parts = s_replaced.split()

    # 恢复日期时间（添加安全检查）
    result = []
    i = 0
    for part in parts:
        if part == placeholder:
            result.append(datetimes)
        else:
            result.append(part)
        if i == 4 and start != "":
            result.append(start)
        i += 1

    return result


def extract_amount(amount_text: str) -> float:
    """
    从形如 '￥58' 的字符串中提取金额数字部分
    """
    match = re.search(r"\d+(\.\d+)?", amount_text)
    if match:
        return float(match.group())
    else:
        return 0.0  # 或者返回 None


def get_xingcheng_date(text_lines):
    lines = []
    for line in text_lines:
        if "年" in line and "月" in line and "日" in line:
            lines.append(line)
        if "申请日期" in line or "申请时间" in line:
            lines.append(line)
    lines.sort(key=sort_key)
    if len(lines)==1:
        return lines[0]
    else :
        for line in lines:
            if ("申请日期" in line or "申请时间" in line) and "年" in line and "月" in line:
                return line
            elif "年" in line and "月" in line and "日" in line:
                return line
            elif "年" in line and "月" in line:
                return line
            elif "申请日期" in line or "申请时间" in line :
                return line
            else:
                return lines[0]
    return None


def sort_key(item):
    # 将元素转为字符串，判断是否包含数字
    item_str = str(item)
    # 若包含数字，返回0（权重低，排前面）；否则返回1（权重高，排后面）
    if re.search(r'\d', item_str):  # 正则匹配数字
        return 0
    else:
        return 1


def get_caocao_date(basic_info_line: str):
    # 提取申请日期
    application_date_str = get_xingcheng_date(basic_info_line.split("|"))
    application_date_str = application_date_str.replace("申请日期：", "").strip()
    return get_date(get_date_info(application_date_str))


def get_didi_date(basic_info_line: str):
    # 提取申请日期
    application_date_str = get_xingcheng_date(basic_info_line.split("·"))
    application_date_str = application_date_str.replace("申请日期：", "").strip()
    return get_date(get_date_info(application_date_str))


def get_gaodei_date(basic_info_line: str):
    # 提取申请日期
    application_date_str = get_xingcheng_date(basic_info_line.split(" "))
    application_date_str = application_date_str.replace("申请日期：", "").strip()
    return get_date(get_date_info(application_date_str))

def get_ditie_date(basic_info_line: str):
    #提取申请日期
    application_date_str = basic_info_line.replace("申请日期：", "").strip()
    return get_date(get_date_info(application_date_str))
    

def get_other_date(basic_info_line: str):
    # 提取申请日期
    application_date_str=get_xingcheng_date(basic_info_line.split(" "))
    application_date_str = application_date_str.replace("申请日期：", "").strip()
    return get_date(get_date_info(application_date_str))



def get_date_info(date_time: str) -> str:
    pattern = r"\d{4}[-/]\d{1,2}[-/]\d{1,2}"
    match = re.search(pattern, date_time)
    if match:
        return match.group(0)
    else:
        return date_time


def get_date_time_info(date_time: str) -> str:
    date_time = convert_to_standard_datetime(date_time)
    if(date_time):
        pattern = r"\d{4}[-/]\d{1,2}[-/]\d{1,2} \d{2}[:]\d{2}"
        match = re.search(pattern, date_time)
        if match:
            return match.group(0)
    else:
        return None

def convert_to_standard_datetime(date_time: str) -> str:
    ## 统一时间格式：yyyy-MM-dd HH:mm
    if not date_time:
        return None  # 处理空输入
    
    # 1. 定义所有可能的日期时间格式正则（覆盖常见场景）
    # 格式1：年-月-日 时:分 / 年/月/日 时:分（纯数字分隔）
    pattern1 = r"(\d{4})[-/](\d{1,2})[-/](\d{1,2})\s+(\d{2}):(\d{2})"
    # 格式2：年.月.日 时:分（点分隔）
    pattern2 = r"(\d{4})\.(\d{1,2})\.(\d{1,2})\s+(\d{2}):(\d{2})"
    # 格式3：年年月日 时:分（带“年/月/日”字，如 2025年09月19日 15:58）
    pattern3 = r"(\d{4})年(\d{1,2})月(\d{1,2})日?\s+(\d{2}):(\d{2})"
    # 格式4：带时间段的场景（如 2025年09月19日 15:58-17:32，提取前半段）
    pattern4 = r"(\d{4})年(\d{1,2})月(\d{1,2})日?\s+(\d{2}):(\d{2})(?=-)"

    # 2. 按优先级匹配正则，提取年、月、日、时、分
    match = None
    parse_format = None  # 标记当前匹配的格式，用于后续解析
    
    # 先匹配带“年/月/日”的格式（更常见）
    if not match:
        match = re.search(pattern3, date_time)
        if match:
            parse_format = "ymd"  # 年、月、日分别对应分组1-3，时-分对应4-5
    
    # 再匹配时间段中的日期时间
    if not match:
        match = re.search(pattern4, date_time)
        if match:
            parse_format = "ymd"
    
    # 匹配纯数字分隔格式（- / .）
    if not match:
        match = re.search(pattern1, date_time) or re.search(pattern2, date_time)
        if match:
            parse_format = "num"  # 年、月、日分别对应分组1-3，时-分对应4-5
    
    # 3. 解析匹配结果，转为标准格式
    if match and parse_format:
        # 提取分组数据（年、月、日、时、分）
        year, month, day, hour, minute = match.groups()
        # 补全单数字为两位数（如 9月→09月，8时→08时）
        month = f"{int(month):02d}"
        day = f"{int(day):02d}"
        hour = f"{int(hour):02d}"
        minute = f"{int(minute):02d}"
        # 拼接为 yyyy-MM-dd HH:mm 格式
        return f"{year}-{month}-{day} {hour}:{minute}"
    
    # 4. 若所有格式都不匹配，返回原始匹配结果（或None，根据需求调整）
    # （可选） fallback：返回原始提取的未格式化字符串
    raw_match = re.search(r"\d{4}[-/年.]\d{1,2}[-/月.]\d{1,2}[日]?\s+\d{2}:\d{2}", date_time)
    return raw_match.group(0) if raw_match else None

def get_date(application_date_str):
    if application_date_str == None:
        return None
    try:
        # 尝试解析 'yyyy-MM-dd' 格式
        return (
            datetime.strptime(application_date_str, "%Y-%m-%d")
            .date()
            .strftime("%Y-%m-%d")
        )
    except ValueError:
        try:
            # 尝试解析 'yyyy年MM月dd日' 格式
            return (
                datetime.strptime(application_date_str, "%Y年%m月%d日")
                .date()
                .strftime("%Y-%m-%d")
            )
        except ValueError:
            print(f"无法解析申请日期: {application_date_str}")
            return None


def get_content(item, keys):
    # 初始化用车时间为空字符串
    use_time = ""
    # 遍历 item 字典的键
    for key_one in keys:
        for key in item:
            if key_one in key:
                use_time = item[key]
                break
    return use_time

def get_content2(item, keys):
    # 初始化用车时间为空字符串
    use_time = ""
    # 遍历 item 字典的键
    for key_one in keys:
        for key in item:
            if key_one in key:
                use_time +=  item[key] if use_time == "" else (" " + item[key])
    return use_time
